package io.flysium.framework.util.ftp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.flysium.framework.util.ftp.FTPUtils.FtpBatchResult;
import io.flysium.framework.util.ftp.FTPUtils.FtpConfig;
import io.flysium.framework.util.ftp.FTPUtils.FtpResult;

/**
 * FTP工具类
 * @author SvenAugustus(蔡政滦)  e-mail: SvenAugustus@outlook.com
 * @version 1.0
 */
final class SendFtpTool {

	private static Logger logger = LoggerFactory.getLogger(SendFtpTool.class);

	private SendFtpTool() {
	}

	public static FTPClient loginFtpServer(FtpConfig config) throws Exception {
		FTPClient client = new FTPClient();
		// connect
		boolean flag;
		try {
			client.setDataTimeout(30000);
			if (-1 != config.getPort()) {
				client.connect(config.getIp_address(), config.getPort());
			} else {
				client.connect(config.getIp_address());
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
			return null;
		}
		flag = client.login(config.getUsername(), config.getPwd());

		//logger.error(config.getIp() + "  " + config.getUsername() + "  " + flag);
		// reply
		if (!flag) {
			logger.error(config.getIp_address() + "  " + config.getUsername() + "--登陆失败");
			return null;
		}
		int reply = client.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			logger.error(config.getIp_address() + "  " + config.getUsername() + "返回" + reply + "--登陆失败");
			client.disconnect();
			return null;
		} else {
			logger.error(config.getIp_address() + "  " + config.getUsername() + "  --登陆成功");
		}

		return client;
	}
	public static FtpResult sendtoftp(FTPClient client, FtpConfig config, File file, String remoteFileNametemp) throws Exception {
		FtpResult ftpResult = new FtpResult();
		ftpResult.setSuc(false);
		ftpResult.setRemoteFileNametemp(remoteFileNametemp);
		ftpResult.setLocalFile(file);
		BufferedInputStream buffIn = null;
		try {
			client.setFileType(FTP.BINARY_FILE_TYPE);
			String ftpClientMode = config.getFtp_client_mode();
			if (ftpClientMode != null && FtpConfig.FTPCLIENTMODE_LOCALPASSIVEMODE.equalsIgnoreCase(ftpClientMode)) {
				client.enterLocalPassiveMode();
			}

			// 设置上传目录
			if (!"/".equals(config.getDest_dir()) && !client.changeWorkingDirectory(config.getDest_dir())) {
				if (!client.makeDirectory(config.getDest_dir())) {
					throw new RuntimeException("创建文件夹" + config.getDest_dir() + "失败");
				}
				client.changeWorkingDirectory(config.getDest_dir());// 再设置一遍
			}
			buffIn = new BufferedInputStream(new FileInputStream(file));
			boolean flag = client.storeFile(remoteFileNametemp, buffIn);
			ftpResult.setSuc(flag);
		} catch (Exception e) {
			logger.error("FTP上传失败", e);
			ftpResult.setSuc(false);
		} finally {
			if (null != buffIn) {
				buffIn.close();
			}
			if (ftpResult != null && ftpResult.isSuc()) {
				logger.info("ip=   " + config.getIp_address() + "  " + remoteFileNametemp + " 发送成功");
			}
		}
		return ftpResult;
	}

	public static FtpResult getofftp(FTPClient client, FtpConfig config, File file, String remoteFileNametemp) throws Exception {
		FtpResult ftpResult = new FtpResult();
		ftpResult.setSuc(false);
		ftpResult.setRemoteFileNametemp(remoteFileNametemp);
		ftpResult.setLocalFile(file);
		BufferedOutputStream buffOut = null;
		try {
			client.setFileType(FTP.BINARY_FILE_TYPE);
			String ftpClientMode = config.getFtp_client_mode();
			if (ftpClientMode != null && FtpConfig.FTPCLIENTMODE_LOCALPASSIVEMODE.equalsIgnoreCase(ftpClientMode)) {
				client.enterLocalPassiveMode();
			}

			// 设置上传目录
			if (!"/".equals(config.getDest_dir()) && !client.changeWorkingDirectory(config.getDest_dir())) {
				client.changeWorkingDirectory(config.getDest_dir());// 再设置一遍
			}
			buffOut = new BufferedOutputStream(new FileOutputStream(file));
			client.retrieveFile(remoteFileNametemp, buffOut);
			ftpResult.setSuc(true);
		} catch (Exception e) {
			logger.error("FTP下载失败", e);
			ftpResult.setSuc(false);
		} finally {
			if (null != buffOut) {
				buffOut.close();
			}
			if (ftpResult != null && ftpResult.isSuc()) {
				logger.info("ip=   " + config.getIp_address() + "  " + remoteFileNametemp + " 下载成功");
			}
		}
		return ftpResult;
	}

	public static FtpBatchResult batchGetofftp(FTPClient client, FtpConfig config, FTPFileFilter ftpFileFilter, boolean rmIfSuc,
			boolean interruptIfError) throws Exception {
		FtpBatchResult ftpBatchResult = new FtpBatchResult(true, new ArrayList<FtpResult>());
		try {
			client.setFileType(FTP.BINARY_FILE_TYPE);
			String ftpClientMode = config.getFtp_client_mode();
			if (ftpClientMode != null && FtpConfig.FTPCLIENTMODE_LOCALPASSIVEMODE.equalsIgnoreCase(ftpClientMode)) {
				client.enterLocalPassiveMode();
			}

			// 设置上传目录
			if (!"/".equals(config.getDest_dir()) && !client.changeWorkingDirectory(config.getDest_dir())) {
				client.changeWorkingDirectory(config.getDest_dir());// 再设置一遍
			}

			FTPFile[] fileList = client.listFiles(config.getDest_dir());
			if (fileList != null) {
				for (int i = 0; i < fileList.length; i++) {
					FTPFile f = fileList[i];
					String remoteFileNametemp = f.getName();
					if (ftpFileFilter == null || (ftpFileFilter != null && ftpFileFilter.filter(remoteFileNametemp))) {

						File localFile = new File(config.getLocal_bak_dir(), remoteFileNametemp);
						BufferedOutputStream buffOut = null;
						try {
							buffOut = new BufferedOutputStream(new FileOutputStream(localFile));
							client.retrieveFile(remoteFileNametemp, buffOut);
							buffOut.close();
							ftpBatchResult.getResult().add(new FtpResult(true, remoteFileNametemp, localFile));
							logger.info("ip=   " + config.getIp_address() + "  " + config.getDest_dir() + "/" + remoteFileNametemp + " 下载成功");
						} catch (Exception e) {
							ftpBatchResult.setSuc(false);
							ftpBatchResult.getResult().add(new FtpResult(false, remoteFileNametemp, localFile));
							if (interruptIfError) {
								throw e;
							}
						} finally {
							if (null != buffOut) {
								buffOut.close();
							}
						}
						if (rmIfSuc) {// 是否文件下载后删除远程ftp文件
							client.deleteFile(remoteFileNametemp);
						}
					}
				}
			}
		} catch (Exception e) {
			ftpBatchResult.setSuc(false);
			logger.error("FTP下载失败", e);
		} finally {
			if (ftpBatchResult != null && ftpBatchResult.isSuc()) {
				logger.info("ip=   " + config.getIp_address() + "  " + config.getDest_dir() + " 下载成功");
			}
		}
		return ftpBatchResult;
	}

}
